package com.syni.mdd.yhd.common.all.utils;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;


/**
 * @className DESUtil
 * @description TOO
 * @Author cfx
 * @DATE 2019/9/5 10:36
 * @VERSION 1.0
 **/
public class DESUtil {
    /*
     * 生成密钥
     */
    private final static String secretKey = "apiMiDongDong0630@@";
    private final static String DESKEY = "6726102c2c7ae0ce";
    public static byte[] initKey() throws Exception{
        KeyGenerator keyGen = KeyGenerator.getInstance("DES");
        SecureRandom secureRandom = new SecureRandom(secretKey.getBytes());
        keyGen.init(56,secureRandom);
        SecretKey secretKey = keyGen.generateKey();
        return secretKey.getEncoded();
        //return secretKey.getBytes();
    }


    /*
     * DES 加密
     */
    public static byte[] encrypt(byte[] data, byte[] key) throws Exception{
        SecretKey secretKey = new SecretKeySpec(key, "DES");

        Cipher cipher = Cipher.getInstance("DES");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
        byte[] cipherBytes = cipher.doFinal(data);
        return cipherBytes;
    }

    /*
     * DES 加密
     */
    public static String encrypt(Integer id) throws Exception{
        byte[] desKey = hexStringToByte(DESKEY);
        byte[] desResult = DESUtil.encrypt(id.toString().getBytes(), desKey);
        System.out.println(id + ">>>DES 加密结果>>>" + bytesToHexString(desResult));
        return bytesToHexString(desResult);
    }


    /*
     * DES 解密
     */
    public static byte[] decrypt(byte[] data, byte[] key) throws Exception{
        SecretKey secretKey = new SecretKeySpec(key, "DES");
        Cipher cipher = Cipher.getInstance("DES");
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] plainBytes = cipher.doFinal(data);
        return plainBytes;
    }

    /*
     * DES 解密
     */
    public static String decrypt(String id) throws Exception{
        byte[] desKey = hexStringToByte(DESKEY);
        byte[] desResult = hexStringToByte(id);
        byte[] desPlain = DESUtil.decrypt(desResult, desKey);
        String decryptStr = new String(desPlain);
        System.out.println(id + ">>>DES 解密结果>>>" + decryptStr);
        return decryptStr;
    }

    //Test
    public static void main(String[] args) throws Exception {
        final String DATA = "15";
        byte[] desKey = DESUtil.initKey();
        System.out.println("DES KEY : " + bytesToHexString(desKey));
        String DESKEY = bytesToHexString(desKey);
        desKey = hexStringToByte(DESKEY);


        byte[] desResult = DESUtil.encrypt(DATA.getBytes(), desKey);
        System.out.println(DATA + ">>>DES 加密结果>>>" + bytesToHexString(desResult));

        byte[] desPlain = DESUtil.decrypt(desResult, desKey);
        System.out.println(DATA + ">>>DES 解密结果>>>" + new String(desPlain));
    }

    public static String bytesToHexString(byte[] src){
        StringBuilder stringBuilder = new StringBuilder("");
        if (src == null || src.length <= 0) {
            return null;
        }
        for (int i = 0; i < src.length; i++) {
            int v = src[i] & 0xFF;
            String hv = Integer.toHexString(v);
            if (hv.length() < 2) {
                stringBuilder.append(0);
            }
            stringBuilder.append(hv);
        }
        return stringBuilder.toString();
    }

    /**
     * 16进制字符串转2进制
     * @param s
     * @return
     */
    public static byte[] hexStringToByte(String hexString){
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }

    /**
     * 字符转为byte
     * @param c
     * @return
     */
    public static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }
}
